﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using UCL.Powersource.Analysis;

namespace UCL.Powersource.Statistics
{
    /// <summary>
    /// Effort statistics estimation class
    /// </summary>
    [Export(typeof(IStatistic))]
    [DataContract(IsReference = true)]
    public abstract class EffortStatisticsBase : WIStateStatisticsBase
    {
        /// <summary>
        /// Calculate tfs project collection configuration statistics
        /// </summary>
        /// <param name="teamProjConfig">tfs stat project collection configuration</param>
        /// <param name="timeFrame">iteration time frame</param>
        /// <param name="qString"></param>
        /// <returns>the number of the work items</returns>
        protected override double? CalculateStatistic(ITfsTeamProjectConfiguration teamProjConfig, ITimeFrame timeFrame, string qString)      
        {

            ITimeFrameIteration iterationTimeFrame = (ITimeFrameIteration)timeFrame;        // Time frame of iteration
            string iterationPath = iterationTimeFrame.GetIterationPathForProject(teamProjConfig);       // Get the iteration path 
            if (iterationTimeFrame.StartDate == null || iterationTimeFrame.FinishDate == null) return null;

            float sum = 0;
            if (timeFrame is ITimeFrameIteration)       // if the time frame is the same as a time frame of iteration
            {
                WorkItemCollection queryResults = GetQueryResults(teamProjConfig, timeFrame, qString);      // then query work items collection and get the stat project collection configuration and time frame of the iteration

                if (queryResults == null) return null;      // if there is no results of query then return null

                int ipcount = 0;
                string itemIPath = "";

                foreach (WorkItem item in queryResults)     // For each work item in query results
                {
                    itemIPath = (string)item.Fields["Iteration Path"].Value;        // Get the itemIpath value from "Iteration Path" field
                     if (itemIPath.StartsWith(iterationPath))       // if the value of the itemIPath starts with iterationPath
                    {
                        ipcount++;      // then count the iteration paths
                        if (ValidState(item))       // Validate the state of the work item
                        {
                            var ef = item.Fields["Effort"].Value;       // Get the value of the work item from the "Effort" field
                            sum += Convert.ToInt32(ef);     // and count the items
                        }
                    }
                }

                if (ipcount == 0) return null;      // if the calculation of iteration path equals to null then return null
            }
            else
            {
                Log.Error(new ArgumentException(), "ITimeFrameDateTime not a valid argument, not implemented yet.", timeFrame);     // otherwise throw an argument exception "ITimeFrameDateTime not a valid argument, not implemented yet."
                return null;
            }

            return sum;
        }

        /// <summary>
        /// Validate the state of the work item
        /// </summary>
        /// <param name="item">work item</param>
        /// <returns>the value of the work item from "State" field which is not equal to the value of state</returns>
        protected override bool ValidState(WorkItem item)
        {
            return (string)item.Fields["State"].Value != State;
        }

    }
}
